//this code from: http://blogs.msdn.com/hippietim/archive/2006/03/24/560010.aspx

using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
using Microsoft.Win32;
namespace TeamFoundationAssemblyLoadTest
{
    class Program
    {
        static void Main(string[] args)
        {
            AppDomain domain = AppDomain.CurrentDomain;
            domain.AssemblyResolve += new ResolveEventHandler(domain_AssemblyResolve);
            //  The following line triggers the AssemblyResolve event to fire because
            //  it uses a class in Microsoft.TeamFoundation.WorkItemTracking.Controls.dll
            //  which is not installed in the GAC or anywhere else convenient.
            ClassThatUsesTeamFoundation.SomeFunction();
        }


        static Assembly domain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            String[] assemblyParams = args.Name.Split(',');
            Debug.Assert(assemblyParams.Length > 0 && !String.IsNullOrEmpty(assemblyParams[0]), "Invalid assembly name arguments passed to domain_AssemblyResolve");
            //  Note that there are additional fields passed that indicate the             
            //  version, public key token, etc.  For this demonstration, we

            //  are just looking at the assembly name.             
            String assemblyName = assemblyParams[0];
            Assembly loadedAssembly = null;
            switch (assemblyName)
            {
                case "Microsoft.TeamFoundation.WorkItemTracking.Controls":
                case "Microsoft.VisualStudio.TeamFoundation":
                    // etc.                    
                    loadedAssembly = LoadVSPrivateAssembly(assemblyName);
                    break;
                default:
                    Debug.Fail(assemblyName + " is not supported by TeamFoundationAssemblyLoadTest.domain_AssemblyResolve");
                    break;
            }
            return loadedAssembly;
        }
        //  This function will load the named assembly from the Visual Studio PrivateAssemblies         
        //  directory.  This is where a number of Team Foundation assemblies are located that are        
        //  not easily accessible to an app.  Fortunately, the .NET loader gives us a shot at         
        //  finding them and we just happen to know where to look.        
        static Assembly LoadVSPrivateAssembly(String assemblyName)
        {
            Assembly loadedAssembly = null;
            using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\VisualStudio\8.0"))
            {
                if (key != null)
                {
                    Object obj = key.GetValue("InstallDir");
                    if ((obj != null) && (obj is String))
                    {
                        String vsInstallDir = obj as String;
                        String privateAssembliesDir = Path.Combine(vsInstallDir, "PrivateAssemblies");
                        String assemblyFile = Path.Combine(privateAssembliesDir, assemblyName + ".dll");
                        loadedAssembly = Assembly.LoadFile(assemblyFile);
                    }
                    else
                    {
                        Debug.Fail("VS 8.0 InstallDir value is missing or invalid");
                    }
                }
                else
                {
                    Debug.Fail("Could not open VS 8.0 registry key");
                }
            }
            return loadedAssembly;
        }
    }
}
